﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleTest
{
    class Program
    {
        public class Segment
        {
            public Segment(string url, int start, int length)
            {
                this.expression = url.Substring(start, length);
                this.start = start;
                this.length = length;
                int left = 0;
                int right = -1;
                int found = 0;
                for (int i = 0; i < expression.Length - 1; i++)
                {
                    if (expression[i] == ':')
                    {
                        if (i < 2)
                        {
                            left = right + 1;
                            right = i;
                            found++;
                            if (found == 1)
                            {
                                this.name = expression.Substring(left, right - left);
                                this.regex = expression.Substring(right + 1);
                            }
                        }
                        else
                        {
                            if (expression[i - 2] == '(' && expression[i - 1] == '?')
                            {

                            }
                            else
                            {

                                found++;
                                if (found == 1)
                                {
                                    left = right + 1;
                                    right = i;
                                    this.name = expression.Substring(left, right - left);
                                    this.regex = expression.Substring(right + 1);
                                }
                                else if (found == 2)
                                {
                                    left = right + 1;
                                    right = i;
                                    this.regex = expression.Substring(left, right - left);
                                    this.format = expression.Substring(right + 1);
                                }
                            }
                        }
                    }

                }
                if (found<1)
                {
                    this.name = expression;
                    this.regex = "[\\S]+";
                }
                else
                {
                    if (this.regex == "string")
                    {
                        this.regex = "[\\S]+";
                    }
                    else if (this.regex == "int")
                    {
                        this.regex = "[0-9]+";
                    }
                    else if (this.regex == "float")
                    {
                        this.regex = "[0-9]*.[0-9]+";
                    }
                    else if (this.regex == "date")
                    {
                        this.regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}";
                    }
                }
            }
            public int start;
            public int length;
            public string expression;
            public string name;
            public string format;
            public string regex;
        }

        public static List<Segment> GetSegmentList(string url)
        {

            char[] chars = url.ToCharArray();
            int leftBraceCount = 0;
            int leftBracePosition = 0;
            int rightBraceCount = 0;
            int rightBracePosition = 0;
            //用于路由
            string actionUrl = string.Empty;
            //用于组装URL
            string formatUrl = string.Empty;
            //用于解析字符串
            string parameterRegex = string.Empty;
            List<Segment> segmentList = new List<Segment>();
            Segment segment = null;
            int firstLeftBracePosition = 0;

            for (int i = 0; i < chars.Length-1; i++)
            {
				if (chars[i] == '{')
                {
					if (chars [i + 1] == '{') {
						//chars[i]='\\';
                        i++;
					} else {
                        if (firstLeftBracePosition == 0)
                        {
                            firstLeftBracePosition = i;
                        }
                        leftBraceCount++;
                        leftBracePosition = i;
                        i++;
					}
                }
                else if (chars[i] == '}')
                {
                    if (chars[i + 1] == '}')
                    {
                        if (leftBraceCount == rightBraceCount)
                        {
                            //chars[i] = '\\';
                            i++;
                        }
                        else
                        {
                            rightBraceCount++;
                            rightBracePosition = i;
                            if (leftBraceCount == rightBraceCount)
                            {
                                segment = new Segment(url, leftBracePosition + 1, rightBracePosition - leftBracePosition - 1);
                                segmentList.Add(segment);
                            }
                        }
                    }
                    else
                    {
                        rightBraceCount++;
                        rightBracePosition = i;
                        
                        if (leftBraceCount == rightBraceCount)
                        {
                            segment = new Segment(url, leftBracePosition + 1, rightBracePosition - leftBracePosition - 1);
                            segmentList.Add(segment);
                        }
                    }
                }
                if (i == chars.Length - 2 && chars[i] !='}' && chars[i+1]=='}')
                {
                    rightBraceCount++;
                    rightBracePosition = i+1;

                    if (leftBraceCount == rightBraceCount)
                    {
                        segment = new Segment(url, leftBracePosition + 1, rightBracePosition - leftBracePosition - 1);
                        segmentList.Add(segment);
                    }
                }
            }
            //生成查找路由的字符串
            actionUrl = url.Substring(0, firstLeftBracePosition).Replace("{{","{").Replace("}}","}");
            formatUrl = url;
            int relitivePosition=0;
            string format = "";
            for (int i = 0; i < segmentList.Count; i++)
            {
                formatUrl = formatUrl.Remove(segmentList[i].start+relitivePosition, segmentList[i].length);
                if (string.IsNullOrEmpty(segmentList[i].format))
                {
                    format = i.ToString();
                }
                else
                {
                    format = i.ToString() + ":" + segmentList[i].format;
                }
                formatUrl = formatUrl.Insert(segmentList[i].start+relitivePosition,format);
                relitivePosition += format.Length - segmentList[i].length;
            }
            //生成生成URL的代码
            string formatParameters="";
            for (int i = 0; i < segmentList.Count; i++)
            {
                formatParameters +=","+ segmentList[i].name;
            }
            string formatCode = string.Format("string.Format(\"{0}\"{1});", formatUrl, formatParameters);
            relitivePosition = 0;
            //生成解析URL的代码
            parameterRegex = url;
            for (int i = 0; i < segmentList.Count; i++)
            {
                parameterRegex = parameterRegex.Remove(segmentList[i].start - 1 + relitivePosition, segmentList[i].length + 2);
                parameterRegex = parameterRegex.Insert(segmentList[i].start-1 + relitivePosition,string.Format("({0})",segmentList[i].regex));
                relitivePosition += segmentList[i].regex.Length - segmentList[i].length;
            }
            parameterRegex = parameterRegex.Replace("{{","{").Replace("}}","}");
            return segmentList;
        }
        //public static string GetFormatMethod(string url,List<Segment> segmentList,string name)
        //{
        //    for (int i = 0; i < segmentList.Count; i++)
        //    {
        //        segmentList[i].start = segmentList[i].length;
        //    }
        //}
        static void Main(string[] args)
        {
            // "/Eidt-{[id:4d}.htm"
            string url = "/Eidt-{id:(?:12)*[0-9]+:3d}-{name}.htm";
            var segs=GetSegmentList(url);
            for (int i = 0; i < segs.Count; i++)
            {
                Console.WriteLine(segs[i].name);
                Console.WriteLine(segs[i].regex);
                Console.WriteLine(segs[i].format);
            }
			Console.ReadKey ();
        }
    }
}
